/**
 * 
 */
package com.pmsco.pms.business;

import java.util.Calendar;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.pmsco.pms.business.dto.LogonRequestDTO;
import com.pmsco.pms.business.dto.LogonReturnDTO;
import com.pmsco.pms.core.constant.PmsConstant;
import com.pmsco.pms.core.domain.PmsUser;
import com.pmsco.pms.services.impl.PmsUserServiceImpl;
import com.pmsco.pms.services.interfaces.PmsUserService;
import com.pmsco.pms.util.PmsMailSender;
import com.pmsco.pms.util.PmsRandomStringGenerator;
import com.pmsco.pms.util.PmsSysInfo;
import com.pmsco.pms.util.PmsUserRole;
import com.pmsco.pms.util.PmsUserSession;

/**
 * @author Long Tran
 *
 */
public class LogonBusiness {
	private static final Logger logger = LoggerFactory.getLogger(LogonBusiness.class);
	private PmsUserService pmsUserService = new PmsUserServiceImpl();
	
	public LogonReturnDTO doLogon(LogonRequestDTO logonRequestDTO) {
		logger.info("Start doLogon");
		LogonReturnDTO logonReturnDTO = new LogonReturnDTO();
		
		logger.debug("Is Admin Logon: " + logonRequestDTO.isAdminLogon());
		logger.debug("User Name: " + logonRequestDTO.getUserName());
		
		String logonUnSuccessView = PmsConstant.userLogon_View;
		String logonSuccessView = PmsConstant.listUser_JspUrl;
		Boolean logonSuccessful = false;
		Boolean isAccountLocked = false;
		
		if(logonRequestDTO.isAdminLogon())
			logonUnSuccessView = PmsConstant.admin_View;
		
		logger.debug("Check password");
		PmsUser logonedUser = pmsUserService.loadPmsUserByName(logonRequestDTO.getUserName());
		if(logonedUser != null) {
			logonSuccessful = logonRequestDTO.getPassword().equals(logonedUser.getPassword()) && PmsConstant.UserActivated.equals(logonedUser.getActivated());
			String userRole = logonedUser.getPmsRole().getRole();
			logger.debug(userRole);
			
			if((!PmsUserRole.ADMIN_USER.getRole().equals(userRole) && logonRequestDTO.isAdminLogon()) || (PmsUserRole.ADMIN_USER.getRole().equals(userRole) && !logonRequestDTO.isAdminLogon()))
				logonSuccessful = false;

			isAccountLocked = PmsConstant.UserLocked.equalsIgnoreCase(logonedUser.getLocked());
			if(isAccountLocked)
				logonSuccessful = false;
		}
		
		logger.debug("Logon Status: " + logonSuccessful);
		
		if(!logonSuccessful) {
			logonReturnDTO.setLogonFail(!logonSuccessful);
			logonReturnDTO.setUserName(logonRequestDTO.getUserName());
			logonReturnDTO.setPassword(logonRequestDTO.getPassword());
			if(logonedUser != null) {
				Integer failLogonCount = logonedUser.getFailLogonCount() + 1;
				if(failLogonCount + 1 == logonRequestDTO.getLogonFailThreshold() && !isAccountLocked)
					logonReturnDTO.setShowWarningMessage(true);
				else if (failLogonCount == logonRequestDTO.getLogonFailThreshold() && !isAccountLocked) {
					logonReturnDTO.setLogonFail(false);
					logonReturnDTO.setShowLockMessage(true);
					logonedUser.setLocked(PmsConstant.UserLocked);
					
					logger.debug("Send email locked account");
					String emailMessage = logonRequestDTO.getEmailBody();
					emailMessage = emailMessage.replace("$1", logonedUser.getUserName());
					emailMessage = emailMessage.replace("$2", "?ref=" + PmsSysInfo.getInstance().getPmsEncoder().encode(logonedUser.getUserName()));
					PmsMailSender.getInstance().sendMail("noreply.pmssystem@gmail.com", logonedUser.getEmailAddr(), logonRequestDTO.getEmailSubject(), emailMessage);
					
				}
				if(!isAccountLocked) {
					logonedUser.setFailLogonCount(failLogonCount);
					pmsUserService.saveOrUpdatePmsUser(logonedUser);
				}
			}
			logonReturnDTO.setReturnView(logonUnSuccessView);
		} else {
			logger.debug("Update last logon time");
			logonedUser.setLastLogonDate(Calendar.getInstance().getTime());
			logonedUser.setFailLogonCount(new Integer(0));
			pmsUserService.saveOrUpdatePmsUser(logonedUser);
			
			logonSuccessView = logonedUser.getPmsRole().getLogonRedirectUrl();
			
			logger.debug("Build PmsUserSession and set to http session");
			PmsUserSession pmsUserSession = new PmsUserSession();
			pmsUserSession.setDetail(logonedUser);

			logonReturnDTO.setPmsUserSession(pmsUserSession);
			logger.debug(logonSuccessView);
			logonReturnDTO.setReturnView(logonSuccessView);
		}
		logger.info("End doLogon");
		return logonReturnDTO;
	}
	
	public LogonReturnDTO doRemindUserName(LogonRequestDTO logonRequestDTO) {
		logger.info("Begin doRemindUserName");
		
		LogonReturnDTO logonReturnDTO = new LogonReturnDTO();
		PmsUser existedUser = pmsUserService.loadPmsUserByEmail(logonRequestDTO.getEmail());
		logger.debug("User name: " + existedUser.getUserName());
		
		logger.debug("Send remind email");
		String emailMessage = logonRequestDTO.getEmailBody();
		emailMessage = emailMessage.replace("$1", existedUser.getUserName());
		PmsMailSender.getInstance().sendMail("noreply.pmssystem@gmail.com", existedUser.getEmailAddr(), logonRequestDTO.getEmailSubject(), emailMessage);
		logonReturnDTO.setReturnView(PmsConstant.doRemindUsername_View);
		
		logger.info("End doRemindUserName");
		return logonReturnDTO;
	}
	
	public LogonReturnDTO doResetPassword(LogonRequestDTO logonRequestDTO) {
		logger.info("Begin doResetPassword");
		
		LogonReturnDTO logonReturnDTO = new LogonReturnDTO();
		PmsUser existedUser = pmsUserService.loadPmsUserByEmail(logonRequestDTO.getEmail());
		logger.debug("User name: " + existedUser.getUserName());
		
		logger.debug("Send reset password email");
		String emailMessage = logonRequestDTO.getEmailBody();
		emailMessage = emailMessage.replace("$1", existedUser.getUserName());
		PmsRandomStringGenerator pmsRandomStringGenerator = new PmsRandomStringGenerator();
		String newPassword = pmsRandomStringGenerator.nextString();
		emailMessage = emailMessage.replace("$2", newPassword);
		PmsMailSender.getInstance().sendMail("noreply.pmssystem@gmail.com", existedUser.getEmailAddr(), logonRequestDTO.getEmailSubject(), emailMessage);
		
		logger.debug("Update user with new password");
		existedUser.setPassword(newPassword);
		pmsUserService.saveOrUpdatePmsUser(existedUser);
		logonReturnDTO.setReturnView(PmsConstant.doResetPassword_View);
		
		logger.info("End doResetPassword");
		return logonReturnDTO;
	}
}
